import java.io.*;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Plan implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    public static ArrayList<Film> films= new ArrayList<>();
    public static ArrayList<Session>  sessions= new ArrayList<>();
    public void addFilm(Film film){
        films.add(film);
    }
    public static void saveStaticData(String filePath) throws IOException {
        // 先写入临时文件，成功后再替换目标文件（避免保存中断导致原文件损坏）
        File tempFile = new File(filePath + ".tmp");
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tempFile))) {
            oos.writeObject(films);
            oos.writeObject(sessions);
            oos.flush(); // 确保数据完全写入
        }
        // 临时文件写入成功后，删除原文件并替换
        File targetFile = new File(filePath);
        if (targetFile.exists() && !targetFile.delete()) {
            throw new IOException("无法替换旧数据文件，请手动删除 " + filePath);
        }
        if (!tempFile.renameTo(targetFile)) {
            throw new IOException("保存数据失败，请检查文件权限");
        }
        System.out.println("电影和场次数据已保存到: " + filePath);
    }
    @SuppressWarnings("unchecked")
    public static void loadStaticData(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            System.out.println("电影/场次数据文件不存在，初始化空列表");
            films = new ArrayList<>();
            sessions = new ArrayList<>();
            return;
        }
        if (file.length() == 0) {
            System.out.println("电影/场次数据文件为空，初始化空列表");
            films = new ArrayList<>();
            sessions = new ArrayList<>();
            return;
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) {
            films = (ArrayList<Film>) ois.readObject();
            sessions = (ArrayList<Session>) ois.readObject();
            System.out.println("已加载电影和场次数据，共 " + films.size() + " 部电影，" + sessions.size() + " 个场次");
        } catch (EOFException e) {
            System.out.println("电影/场次数据文件不完整，初始化空列表");
            films = new ArrayList<>();
            sessions = new ArrayList<>();
        } catch (Exception e) {
            System.out.println("加载电影/场次数据失败：" + e.getMessage() + "，初始化空列表");
            films = new ArrayList<>();
            sessions = new ArrayList<>();
        }
    }
    public ArrayList<Film> sortFilms() {
        ArrayList<Film> sortedFilms = new ArrayList<>(films);
        // 降序
        for (int i = 0; i < sortedFilms.size() - 1; i++) {
            for (int j = 0; j < sortedFilms.size() - i - 1; j++) {
                if (sortedFilms.get(j).getGrade() < sortedFilms.get(j + 1).getGrade()) { // 降序判断
                    Film temp = sortedFilms.get(j);
                    sortedFilms.set(j, sortedFilms.get(j + 1));
                    sortedFilms.set(j + 1, temp);
                }
            }
        }
        return sortedFilms;
    }
    public void arrangeFilms() {//自动排片
        ArrayList<Film> sortedFilms = sortFilms();
        ArrayList<LocalDateTime> goldTimes = new ArrayList<>();
        ArrayList<LocalDateTime> normalTimes = new ArrayList<>();
        for (LocalDateTime times: generateCandidateTimes(7,30)) {
            if(isGoldTime(times)) {
                goldTimes.add(times);
            }
            else{
                normalTimes.add(times);
            }
        }
        arrangeFilmsToTimes(sortedFilms, goldTimes, true);
        arrangeFilmsToTimes(sortedFilms, normalTimes, false);
    }
    public ArrayList<LocalDateTime> generateCandidateTimes(int days, int intervalMinutes) {//生成可用时间段
        ArrayList<LocalDateTime> times = new ArrayList<>();
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime end = start.plusDays(days); // 排片截止到未来N天
        LocalDateTime current = start;
        while (current.isBefore(end)) {
            int hour = current.getHour();
            if (hour >= 8 && hour < 23) {
                times.add(current);
            }
            current = current.plusMinutes(intervalMinutes);
        }
        return times;
    }
    public static boolean isGoldTime(LocalDateTime time) {
        DayOfWeek day = time.getDayOfWeek(); // 星期几（1=周一，7=周日）
        int hour = time.getHour(); // 小时（0-23）

        if (day.getValue() >= 1 && day.getValue() <= 5) { // 工作日
            return hour >= 19 && hour < 22; // 19:00-22:00
        } else { // 周末
            return hour >= 14 && hour < 22; // 14:00-22:00
        }
    }
    public void arrangeFilmsToTimes(List<Film> films, List<LocalDateTime> targetTimes, boolean isPrime) {
        for(Film film: films){
            if (film.isOnBoard()) {
                continue;
            }
            for(LocalDateTime time : new ArrayList<>(targetTimes)){
                for(Screenroom rooms:Screenroom.values()){
                    if(rooms.isAvailable(film, time)){
                        Session sn=new Session(film,rooms,time);
                        sessions.add(sn);
                        targetTimes.remove(time);
                    }
                    break;
                }
            }
        }
    }

}
